﻿using ShanNiang.XkmWork.Services.Events;
using ShanNiang.XkmWork.Services.Interfaces;
using SharpHook;
using SharpHook.Data;
using System.Text;

namespace ShanNiang.XkmWork.Services.Implementations
{
    public class ScanerService : IScanerService
    {
        #region fields
        private readonly TaskPoolGlobalHook _hook;
        private readonly StringBuilder _buffer = new();
        private DateTime _lastKeyTime = DateTime.MinValue;
        private readonly Timer _timeoutTimer;
        private bool _isShiftPressed = false;
        private bool _isCapsLockOn = false;
        private const int ScanTimeoutMs = 100;

        public event EventHandler<CodeEventArges>? BarcodeScanned;

        //const string unshifChars = "`1234567890-=[];',./";
        //const string inshifChars = "~!@#$%^&*()_+{}:\"<>?";

        #endregion

        public ScanerService()
        {
            _hook = new TaskPoolGlobalHook();
            _hook.KeyPressed += OnKeyPressed;
            _hook.KeyReleased += OnKeyReleased;
            _timeoutTimer = new Timer(_ => ClearBuffer(), null, Timeout.Infinite, Timeout.Infinite);
            _isCapsLockOn = GetInitialCapsLockState();
        }


        private bool GetInitialCapsLockState()
        {
            // 通过SharpHook事件订阅检测当前状态
            bool currentState = false;
            var resetEvent = new ManualResetEvent(false);

            using var tempHook = new TaskPoolGlobalHook();
            tempHook.KeyPressed += (_, e) =>
            {
                if (e.Data.KeyCode == KeyCode.VcCapsLock)
                {
                    currentState = !currentState;
                    resetEvent.Set();
                }
            };

            tempHook.RunAsync();

            // 发送物理Caps Lock按键事件（需用户手动触发）
            Console.WriteLine("请手动按下Caps Lock键以检测初始状态...");
            if (!resetEvent.WaitOne(2000))
            {
                Console.WriteLine("未检测到Caps Lock按键，使用默认状态");
            }

            return currentState;
        }


        private void OnKeyPressed(object? sender, KeyboardHookEventArgs e)
        {
            _timeoutTimer.Change(ScanTimeoutMs, Timeout.Infinite);

            switch (e.Data.KeyCode)
            {
                case KeyCode.VcEnter:
                    var barcode = _buffer.ToString();
                    ClearBuffer();
                    BarcodeScanned?.Invoke(this, new CodeEventArges(barcode));
                    break;

                case KeyCode.VcLeftShift:
                case KeyCode.VcRightShift:
                    _isShiftPressed = true;
                    break;

                case KeyCode.VcCapsLock:
                    _isCapsLockOn = !_isCapsLockOn;
                    break;

                default:
                    if ((DateTime.Now - _lastKeyTime).TotalMilliseconds > ScanTimeoutMs)
                        ClearBuffer();

                    _buffer.Append(KeyCodeToChar(e.Data.KeyCode));
                    _lastKeyTime = DateTime.Now;
                    break;
            }
        }

        private char KeyCodeToChar(KeyCode keyCode)
        {
            bool isLetterShifted = _isShiftPressed ^ _isCapsLockOn;

            // 字母键处理（受CapsLock和Shift双重影响）
            if (keyCode >= KeyCode.VcA && keyCode <= KeyCode.VcZ)
                return isLetterShifted ? (char)keyCode : (char)(keyCode + 32);

            // 数字和符号键（仅受Shift影响）
            return keyCode switch
            {
                // 数字行符号
                KeyCode.Vc1 => _isShiftPressed ? '!' : '1',
                KeyCode.Vc2 => _isShiftPressed ? '@' : '2',
                KeyCode.Vc3 => _isShiftPressed ? '#' : '3',
                KeyCode.Vc4 => _isShiftPressed ? '$' : '4',
                KeyCode.Vc5 => _isShiftPressed ? '%' : '5',
                KeyCode.Vc6 => _isShiftPressed ? '^' : '6',
                KeyCode.Vc7 => _isShiftPressed ? '&' : '7',
                KeyCode.Vc8 => _isShiftPressed ? '*' : '8',
                KeyCode.Vc9 => _isShiftPressed ? '(' : '9',
                KeyCode.Vc0 => _isShiftPressed ? ')' : '0',

                // 符号键
                KeyCode.VcBackQuote => _isShiftPressed ? '~' : '`',
                KeyCode.VcMinus => _isShiftPressed ? '_' : '-',
                KeyCode.VcEquals => _isShiftPressed ? '+' : '=',
                KeyCode.VcOpenBracket => _isShiftPressed ? '{' : '[',
                KeyCode.VcCloseBracket => _isShiftPressed ? '}' : ']',
                KeyCode.VcBackslash => _isShiftPressed ? '|' : '\\',
                KeyCode.VcSemicolon => _isShiftPressed ? ':' : ';',
                KeyCode.VcQuote => _isShiftPressed ? '"' : '\'',
                KeyCode.VcComma => _isShiftPressed ? '<' : ',',
                KeyCode.VcPeriod => _isShiftPressed ? '>' : '.',
                KeyCode.VcSlash => _isShiftPressed ? '?' : '/',

                // 特殊键
                KeyCode.VcSpace => ' ',
                KeyCode.VcTab => '\t',

                _ => '\0'
            };
        }

        private void OnKeyReleased(object? sender, KeyboardHookEventArgs e)
        {
            if (e.Data.KeyCode == KeyCode.VcLeftShift || e.Data.KeyCode == KeyCode.VcRightShift)
                _isShiftPressed = false;
        }
        private void ClearBuffer()
        {
            _buffer.Clear();
            _lastKeyTime = DateTime.MinValue;
        }

        public void Dispose()
        {
            _hook.Dispose();
        }

        public async Task StartAsync(CancellationToken cancellationToken)
        {
            await _hook.RunAsync();
        }

        public async Task StopAsync(CancellationToken cancellationToken)
        {
            await Task.Run(() =>
            {
                _hook.Stop();
                _hook.Dispose();
                _timeoutTimer.Dispose();
                GC.SuppressFinalize(this);
            }, cancellationToken);
        }
    }
}
